<?php


class XmlChart 
{
  protected $graph = '';
  protected $head = '';
  protected $singleSets = '';
  protected $dataSets = '';
  protected $categorySets = '';
  
  private function getChartOptions($chartType)
  {
    $ret = null;
    switch($chartType) {
      case 'Column2D':
      case 'Column3D':
        $ret = array( 
          'useRoundEdges' => '1',
          'palette' => '2',
          'decimals' => "0",
          'formatNumberScale' => "0",
        );
        break;
      case 'Pie2D':
      case 'Pie3D':
        $ret = array(
          'palette' => '4', 
          'decimals' => "0",
          'enableSmartLabels' => '1', 
          'enableRotation' => '0', 
          'showBorder'=> '1', 
          'startingAngle'=>'70',
          'showNames' => '1',
          'showPercentValues' => '1', 
          'pieSliceDepth' => '30', 
        );
        break;
      case 'Bar2D':
      case 'Bar3D':
      default:
        $ret = array('useRoundEdges' => '1');
        break;
    }
    return $ret;
  }
  public function __construct($chartType, $caption = " ", $subcaption=null, $save = null, $options = null)
  {
      $caption = isset($caption) ? 'caption="'.$caption.'"' : '';
      $subcaption = isset($subcaption) ? 'subcaption="'.$subcaption.'"' : '';
      $others = '';
      if ($options) {
        $options = array_merge($options, $this->getChartOptions($chartType));
      } else {
        var_dump($chartType);
        $options = $this->getChartOptions($chartType);
      }
      foreach ($options as $option => $value) {
        $others .= $option.'="'.$value.'" ';
      }
      if ($save) {
        $saves =  "exportEnabled='1' exportHandler='/report/saveChart' exportAtClient='0' exportAction='download'"; 
        //$saves = "imageSave='1' imageSaveURL='/report/saveChart'";
      }
      $this->head = "<chart ${saves} ${caption} ${subcaption} ${others}>";
  }
  
  // we need [["name" => name, "value" => value, "link" => link], []]
  protected function addSet($values, $max = 0)
  {
    $format = '<set %s %s %s />';
    $total = '';
    if ($max) {
      $val = null;
      foreach($values as $key => $row) {
        $val[$key] = $row['value'];
      }
      array_multisort($val, SORT_DESC, $values);
    }
    
    
    $max = $max == 0 ? count($values) + 1 : $max;
    $otherValue = 0;
    foreach($values as $i => $value) {
      if ($i >= $max - 1) {
        $otherValue += $value['value'];
      } else {
        $name  = isset($value['name']) ? 'name="'.$value['name'].'"' : '';
        $val = 'value="'.$value['value'].'"';
        $link  = isset($value['link']) ? 'link=\'javascript:getItem("'.$value['link'].'");\'' : '';
        $total .= sprintf($format, $val, $name, $link);
      } 
    }
    if ($otherValue) {
      $total .= sprintf($format, 'value="'.$otherValue.'"', 'name="'.Others.'"', '');
    }
    return $total;
  }
  
  public function addSingleSet($values, $max = 8)
  {
    $this->singleSets = $this->addSet($values, $max);
  }

  public function addCategorySet($values)
  {
    if ($this->categorySets != '') {
      throw new Exception('this function cannot be called twice.');
    }
    // <categories font="Arial" fontSize="11" fontColor="000000">
    $head = '<categories font="Verdana">'; 
    //<category name="N. America" hoverText="North America" /> 
    $format = '<category %s %s />';
    
    $total = '';
    foreach($values as $value) {
      $name = 'name="'.$value['name'].'"';
      $hover  = isset($value['hoverText']) ? 'hoverText="'.$value['hoverText'].'"' : '';
      $total .= sprintf($format, $name, $hover); 
    }
    $this->categorySets = $head.$total.'</categories>';
  }
  
  public function addDataSet($name, $values, $options = null)
  {
    //<dataset seriesName='2005' parentYAxis='P' color='Fad35e' numberPrefix='$'>
    $format = '<dataset %s %s>';
    $name = 'seriesName="'.$name.'"';
    $others = '';
    foreach ($options as $option => $value) {
      $others .= $option.'="'.$value.'" ';
    }
    $head = sprintf($format, $name, $others);
    $total = $this->addSet($values);
    $this->dataSets .= $head.$total.'</dataset>';
  }
  
  protected function renderSingle()
  {
    return $this->head.$this->singleSets.'</chart>';
  }
  
  protected function renderMultiple()
  {
    return $this->head.$this->categorySets.$this->dataSets.'</chart>';
  }
  
  public function render()
  {
    if ($this->singleSets != '') {
      return $this->renderSingle();
    } else {
      return $this->renderMultiple();
    }
  }
}

class XmlChartPie extends XmlChart
{
  public function __construct($caption=null, $subcaption=null)
  {
    $options = array (
      'showNames' => '1',
      'showPercentValues' => '1', 
      'showPercentageInLabel' => '1', 
      'pieSliceDepth' => '30', 
      'showBorder' => '1', 
      'decimalPrecision' => '2'
    );
    parent::__construct($caption, $subcaption, $options);
  }
  
  public function render()
  {
    return $this->renderSingle();
  }
}

class XmlChartColumn extends XmlChart
{
  public function __construct($xAxis, $yAxis, $caption=null, $subcaption=null)
  {
    $options = array (
      'xAxisName' => $xAxis,
      'yAxisName' => $yAxis,
      'decimals' => "0",
      'formatNumberScale' => "0",

    );
    parent::__construct($caption, $subcaption, $options);
  }
  
  public function render()
  {
    if ($this->singleSets != '') {
      return $this->renderSingle();
    } else {
      return $this->renderMultiple();
    }
  }
}